package com.h5lib.server;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.h5lib.server.annotation.Before;
import com.h5lib.server.annotation.Controller;
import com.h5lib.server.annotation.Init;
import com.h5lib.server.annotation.Inject;
import com.h5lib.server.annotation.Jdbc;
import com.h5lib.server.annotation.Repository;
import com.h5lib.server.annotation.RequestMapping;
import com.h5lib.server.annotation.Service;

public class Di {
	
	public static void initDi() throws DiException {
		try {
			List<Class<?>> iocClasses = CoreConfig.iocClasses;
			// bean
			for (int i = 0; i < iocClasses.size(); i++) {
				Class<?> iocClass = iocClasses.get(i);
				Service service = iocClass.getAnnotation(Service.class);
				Repository repository = iocClass.getAnnotation(Repository.class);
				Controller controller = iocClass.getAnnotation(Controller.class);
				if (service != null || repository != null || controller != null) {
					// 初始化大类
					CoreConfig.IOC.put(iocClass, iocClass.newInstance());
					if(controller != null){
						java.lang.reflect.Method[] methods = iocClass.getMethods();
						for (java.lang.reflect.Method method : methods) {
							RequestMapping annotation = method.getAnnotation(RequestMapping.class);
							if (annotation != null) {
								UriMapping uriMapping = new UriMapping();
								uriMapping.setClazz(iocClass);
								uriMapping.setMethod(method);
								//=======配置拦截器==========
								//获取方法上的拦截器
								List<Interceptor> interceptors = new ArrayList<Interceptor>();
								Before before = method.getAnnotation(Before.class);
								if(before != null){
									Class<?>[] values = before.value();
									if(values != null){
										for (Class<?> value : values) {
											interceptors.add((Interceptor)value.newInstance());
										}
									}
								}
								//获取类名上的拦截器
								before = iocClass.getAnnotation(Before.class);
								if(before != null){
									Class<?>[] values = before.value();
									if(values != null){
										for (Class<?> value : values) {
											interceptors.add((Interceptor)value.newInstance());
										}
									}
								}

								uriMapping.setInterceptors(interceptors);
								//=======================
								CoreConfig.requestMapping.put(annotation.value()[0],uriMapping);
							}
						}
					}
				}
				Jdbc jdbc = iocClass.getAnnotation(Jdbc.class);
				if (jdbc != null) {
					String value = jdbc.value();
					CoreConfig.IOC.put(
							iocClass,
							iocClass.getConstructor(String.class).newInstance(value));
					if (jdbc.parent()) {
						CoreConfig.IOC.put(iocClass.getSuperclass(),
								CoreConfig.IOC.get(iocClass));
					}

				}

			}
			// 依赖注入
			for (int i = 0; i < iocClasses.size(); i++) {
				Class<?> iocClass = iocClasses.get(i);
				Field[] fields = iocClass.getDeclaredFields();
				for (Field field : fields) {
					Inject inject = field.getAnnotation(Inject.class);
					Class<?> type = field.getType();
					field.setAccessible(true);
					if (inject != null) {
						field.set(CoreConfig.IOC.get(iocClass),
								CoreConfig.IOC.get(type));
					}

				}
			}
			// 初始化所有init参数为@init的方法
			for (int i = 0; i < iocClasses.size(); i++) {
				Class<?> iocClass = iocClasses.get(i);
				java.lang.reflect.Method[] methods = iocClass.getMethods();
				for (java.lang.reflect.Method method : methods) {
					Init init = method.getAnnotation(Init.class);
					if (init != null) {
						method.invoke(CoreConfig.IOC.get(iocClass));
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new DiException();
		}

	}
	
	public static class UriMapping implements Serializable{
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 328464042894217607L;
		/**
		 * 类
		 */
		private Class<?> clazz;
		/**
		 * 方法
		 */
		private Method method;
		/**
		 * 拦截器
		 */
		private List<Interceptor> interceptors;
		
		public Class<?> getClazz() {
			return clazz;
		}
		public void setClazz(Class<?> clazz) {
			this.clazz = clazz;
		}
		public Method getMethod() {
			return method;
		}
		public void setMethod(Method method) {
			this.method = method;
		}
		public List<Interceptor> getInterceptors() {
			return interceptors;
		}
		public void setInterceptors(List<Interceptor> interceptors) {
			this.interceptors = interceptors;
		}
		
	}
	
	public static class CoreConfig implements Serializable{
		
			/**
			 * 
			 */
			private static final long serialVersionUID = -3234902557337564758L;
			/**
			 * 映射关系
			 */
			public static Map<String, UriMapping> requestMapping = new HashMap<String, UriMapping>();

			/**
			 * 依赖注入Class
			 */
			public static List<Class<?>> iocClasses = new ArrayList<Class<?>>();
			
			/**
			 * IOC容器
			 */
			public static Map<Class<?>, Object> IOC = new HashMap<Class<?>, Object>();
			
			
	}
}


